package com.ttpai.boot.lbs.util;

/**
 * Created by kail on 2017/2/23.
 */
public class LLUtil {

    private static final Float EARTH_RADIUS = 6378.137F; // 赤道半径 6378.137Km ；两极半径 6359.752Km；平均半径 6371.012Km ；赤道周长 40075.7Km
    private static final Float R = EARTH_RADIUS;

    /**
     * 弧度
     * <p>
     * 弧长 = 2πr * (角度/360) =πr * (角度/180) =
     */
    private static double rad(double du) {
        return Math.PI * (du / 180.0D); // 弧度 * 半径 = 弧长
    }

/**
 * 球面直线距离 = r*arccos(sin(x1)*sin(x2) + cos(x1)*cos(x2)*cos(y1-y2) )
 * http://blog.163.com/jey_df/blog/static/182550161201391022632555/
 *
 * @param lng1 经度
 * @param lat1 纬度
 */
public static double getLinearDistance(double lng1, double lat1, double lng2, double lat2) {
    return Math.round(EARTH_RADIUS * Math.acos(Math.sin(rad(lat1)) * Math.sin(rad(lat2)) + Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.cos(Math.abs(rad(lng1) - rad(lng2)))) * 10000D) / 10000D;
}

    public static double distHaversineRAD(double lon1, double lat1, double lon2, double lat2) {
        double hsinX = Math.sin((lon1 - lon2) * 0.5);
        double hsinY = Math.sin((lat1 - lat2) * 0.5);
        double h = hsinY * hsinY + (Math.cos(lat1) * Math.cos(lat2) * hsinX * hsinX);
        return 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h)) * 6367000;
    }

    /**
     * 经纬度之间需要多长时间 (默认每公里4分钟)
     */
    public static double linearDistance2Sec(double lng1, double lat1, double lng2, double lat2) {
        return linearDistance2Sec(lng1, lat1, lng2, lat2, 4);
    }

    /**
     * 经纬度之间需要多长时间 ≈
     *
     * @param factor 每公里需要多少分钟
     */
    public static double linearDistance2Sec(double lng1, double lat1, double lng2, double lat2, double factor) {

        double distanceKM = LLUtil.getLinearDistance(lng1, lat1, lng2, lat2); // 经纬度之间相距多少公里

        // 小于一公里忽略时间
        if (distanceKM < 0.5D) {
            return 0D;
        }

        return distanceKM * factor * 60D; // 需要多少秒
    }

    /**
     * 获取直角距离
     *
     * @param lng1 经度
     * @param lat1 纬度
     */
    public static double getRightAngleDistance(double lng1, double lat1, double lng2, double lat2) {
        double c = getLinearDistance(lng1, lat1, lng2, lat2);
        double lat = rad(Math.abs(lat2 - lat1)) * R; // 维度距离

        return Math.sqrt(Math.pow(c, 2) - Math.pow(lat, 2)) + lat;
    }

    /**
     * 经纬度之间需要多长时间 (默认每公里4分钟)
     */
    public static double rightAngleDistance2Sec(double lng1, double lat1, double lng2, double lat2) {
        return rightAngleDistance2Sec(lng1, lat1, lng2, lat2, 4);
    }

    /**
     * 经纬度之间需要多长时间 ≈
     *
     * @param factor 每公里需要多少分钟
     */
    public static double rightAngleDistance2Sec(double lng1, double lat1, double lng2, double lat2, double factor) {

        double distanceKM = LLUtil.getRightAngleDistance(lng1, lat1, lng2, lat2); // 经纬度之间相距多少公里

        // 小于一公里忽略时间
        if (distanceKM < 0.5D) {
            return 0D;
        }

        return distanceKM * factor * 60D; // 需要多少秒
    }

    /**
     * 6.6666
     * 12.1621
     * <p>
     * 8.19675736426662
     * 17.199482728132914
     */
    public static void main(String[] args) {

        System.out.println(getLinearDistance(121.437236, 31.240008, 121.369699, 31.255901)); // 智慧广场到丰庄茶城 6.6666
        System.out.println(getLinearDistance(121.437236, 31.240008, 121.347473, 31.162281)); // 智慧广场到七宝 12.1621


        System.out.println(distHaversineRAD(121.437236, 31.240008, 121.369699, 31.255901)); // 智慧广场到丰庄茶城 6.6666
        System.out.println(distHaversineRAD(121.437236, 31.240008, 121.347473, 31.162281)); // 智慧广场到七宝 12.1621

        System.out.println();
        System.out.println(getRightAngleDistance(121.437236, 31.240008, 121.369699, 31.255901)); // 智慧广场到丰庄茶城 8.19675736426662
        System.out.println(getRightAngleDistance(121.437236, 31.240008, 121.347473, 31.162281)); // 智慧广场到七宝 17.199482728132914

        System.out.println();
        System.out.println(rightAngleDistance2Sec(121.437236, 31.240008, 121.369699, 31.255901, 4) / 60); // 智慧广场到丰庄茶城 8.19675736426662
        System.out.println(rightAngleDistance2Sec(121.437236, 31.240008, 121.347473, 31.162281, 4) / 60); // 智慧广场到七宝 17.199482728132914

    }

}
